package com.supplychain.financial.parent.common.thread;

import com.supplychain.financial.parent.common.util.ExcelUtil;
import com.supplychain.financial.parent.common.util.HttpClientUtil;
import com.supplychain.financial.parent.common.util.StringUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by zhengchuan on 2017/6/16.
 */
public class BindCarThread implements Runnable {
    private String name;
    private Thread thread;
    private String fileName;
    private List<Map<String, String>> params = new ArrayList<>();
    private List<Map<String, String>> resultList = new ArrayList<>();
    private String excelResultFilePath = "/home/platformUploadExcel/result/";

    public BindCarThread(String name, List<Map<String, String>> params, String fileName) {
        this.name = name;
        this.params = params;
        this.fileName = fileName;
    }

    @Override
    public void run() {
        System.out.println("批量绑卡线程开始了。。。");

        final String doCustAuthUrl = "http://10.95.0.233:23912/clouderp-cgt-order-rest/api/cgt/order/doCustAuth";
        final String doCancelCustAuthUrl = "http://10.95.0.233:23912/clouderp-cgt-order-rest/api/cgt/order/doCancelCustAuth";
        final String getMerIdUrl = "http://10.95.0.233:23912/clouderp-cgt-order-rest/api/cgt/order/getMerchant";
        final String bindCarUrl = "http://10.95.0.233:23912/clouderp-pay-rest/api/pay/bindBankCard";

        List<Map<String, String>> realParams = this.transformParams(params);
        System.out.println("批量绑卡-绑卡数据为 ： " + realParams);

        for (Map<String, String> param : realParams) {

            try {
                resultList.add(param);
                if (param.get("custPwd") != null && !param.get("custPwd").trim().equals("")) {
                    Map<String, String> para = new HashMap<>(1, 1.0F);
                    para.put("userId", "-88");

                    //取消授权
                    String responseRe1 = HttpClientUtil.sendPostRequest(doCancelCustAuthUrl, para, null, null);
                    System.out.println("批量绑卡，取消授权  params : " + para + ", result : " + responseRe1);
                    try {
                        JSONObject jsonObject1 = JSONObject.fromObject(responseRe1);
                        if (jsonObject1.size() == 0 || !"000".equals(jsonObject1.get("code"))) {
                            param.put("authorizationResult", "授权准备失败：" + jsonObject1.get("msg").toString());
                        } else {
                            //去授权
                            para.put("shopId", "");
                            para.put("custCode", param.get("customerId"));
                            para.put("custPwd", param.get("custPwd"));
                            while (true){
                                String responseRe2 = HttpClientUtil.sendPostRequest(doCustAuthUrl, para, null, null);
                                System.out.println("批量绑卡，新商盟授权  params : " + para + ", result : " + responseRe2);
                                try {
                                    JSONObject jsonObject = JSONObject.fromObject(responseRe2);
                                    if (jsonObject.get("msg").toString().equals("获取客户出现了问题，请稍后重试")){
                                        Thread.sleep(6000);
                                        continue;
                                    }
                                    param.put("authorizationResult",  jsonObject.get("msg").toString());
                                    break;
                                } catch (Exception e) {
                                    param.put("authorizationResult", "授权服务器异常");
                                    break;
                                }
                            }

                        }

                    } catch (Exception e) {
                        param.put("authorizationResult", "授权准备失败：服务器异常");
                    }


                } else {
                    param.put("authorizationResult", "缺少新商盟密码");
                }


                if (param.get("accNo") == null || param.get("accNo").trim().equals("")) {
                    param.put("bindCarResult", "缺失银行卡信息");
                    throw new Exception("批量绑卡-缺失银行卡信息，只做了授权操作");
                }

                if (param.get("cardType") == null) {
                    param.put("bindCarResult", "获取银行卡类型失败，请检查卡号然后重试");
                    throw new Exception("批量绑卡-获取银行卡类型失败，只做了授权操作");
                }


                String regex = "^1[34578]\\d{9}$";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher(param.get("nbr"));
                if (!matcher.matches()) {
                    param.put("bindCarResult", "电话号码有误，请检查");
                    throw new Exception("批量绑卡-电话号码有误，只做了授权操作");
                }

                //针对客户授权成功的情况，休眠一下保证同步到支付系统
                if (param.get("authorizationResult").equals("客户授权成功!")) {
                    Thread.sleep(2000);
                }

                //获取MerCode
                Map<String, String> par = new HashMap<>(1, 1.0F);
                par.put("custCode", param.get("customerId"));
                String responseResult = HttpClientUtil.sendPostRequest(getMerIdUrl, par, null, null);
                System.out.println("批量绑卡，根据CustCode获取MerCode  params : " + par + ", result : " + responseResult);

                try {
                    JSONObject jsonObject = JSONObject.fromObject(responseResult);
                    if (jsonObject.size() == 0 || !"000".equals(jsonObject.get("code"))) {
                        param.put("bindCarResult", "获取新商盟信息(MerCode)失败：" + jsonObject.get("msg").toString());
                        System.out.println("批量绑卡，根据CustCode获取MerCode失败  params : " + param);
                        throw new Exception("批量绑卡，根据CustCode获取MerCode失败");
                    } else {
                        JSONObject data = JSONObject.fromObject(jsonObject.get("data"));
                        param.put("merId", data.get("merchantCode").toString());
                    }
                } catch (JSONException e) {
                    param.put("bindCarResult", "获取新商盟信息(MerCode)失败：服务器异常");
                    throw new Exception("获取新商盟信息(MerCode)失败：服务器异常");
                }

                //针对客户授权成功的情况，休眠一下保证同步到支付系统
                if (param.get("authorizationResult").equals("客户授权成功!")) {
                    Thread.sleep(5000);
                }

                for (int i = 0; i<3; i++) {
                    //绑卡
                    String responseResult1 = HttpClientUtil.sendPostRequest(bindCarUrl, param, null, null);
                    System.out.println("批量绑卡，绑卡操作  params : " + param + ", result : " + responseResult1);
                    try {
                        JSONObject jsonObject = JSONObject.fromObject(responseResult1);
                        if (jsonObject.get("code").toString().equals("000")) {
                            param.put("bindCarResult", "绑卡成功！");
                            break;
                        }else {
                            if (jsonObject.get("msg").toString().equals("重复交易")){
                                param.put("bindCarResult", "绑卡成功！(该卡已经绑定过)");
                                break;
                            }else if (jsonObject.get("msg").toString().equals("查无此客户信息")) {
                                param.put("bindCarResult", jsonObject.get("msg").toString());
                                Thread.sleep(10000);
                            }
                            else {
                                param.put("bindCarResult", jsonObject.get("msg").toString());
                                break;
                            }
                        }
                    } catch (Exception e) {
                        param.put("bindCarResult", "绑卡操作失败：服务器异常");
                        Thread.sleep(10000);
                    }
                }

                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        System.out.println("批量绑卡结果："+resultList );
        saveResult(resultList);
        System.out.println("批量绑卡结束了。。。");
    }

    private void saveResult(List<Map<String, String>> resultList) {
        Map<String, String> map = new HashMap<>();
        map.put("sheetName", "客户信息上传结果");
        resultList.add(0,map);

        String[] Keys = new String[]{"customerId","custPwd","accNo","nbr","name","certCode","originalExpireDate","cvn2","authorizationResult","bindCarResult"};
        String[] columnNames = new String[]{"客户编码","客户密码","支付银行卡号","银行卡预留手机号","持卡人姓名","持卡人身份证","银行号有效期月/年(信用卡必填)","信用卡CNV码(信用卡必填)","授权结果","绑卡结果"};
        HSSFWorkbook wb = ExcelUtil.createHSSFWorkbook1(resultList, Keys, columnNames);
        File file = new File(excelResultFilePath + fileName);
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            wb.write(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void start() {
        if (this.thread == null) {
            this.thread = new Thread(this, this.name);
        }
        this.thread.start();
    }

    public List<Map<String, String>> transformParams(List<Map<String, String>> params) {
        List<Map<String, String>> results = new ArrayList<>();
        for (Map<String, String> param : params) {
            if (param.get("客户编码") == null || param.get("客户编码").trim().equals("")) {
                continue;
            }
            Map<String, String> result = new HashMap<>(18, 1.0F);
            result.put("tradeSubType", "DK");
            result.put("merId", "");
            result.put("userId", "770");

            String customerId = param.get("客户编码");
            if (customerId.indexOf("E")!=-1) {
                BigDecimal bd = new BigDecimal(customerId);
                customerId = bd.toPlainString();
            }
            result.put("customerId", customerId);

            String password = param.get("客户密码");
            System.out.println("客户密码："+password);
            if (password != null && !password.equals("") && password.endsWith(".0")) {
                password = password.substring(0,password.length()-2);
                System.out.println("客户密码1："+password);
            }
            if (StringUtils.isNot_NullOrTrimEmpty(password) && password.indexOf("E")!=-1) {
                BigDecimal bd = new BigDecimal(password);
                password = bd.toPlainString();
                System.out.println("客户密码2："+password);
            }
            System.out.println("客户密码3："+password);
            result.put("custPwd", password);

            String accNo = param.get("支付银行卡号");
            if (StringUtils.isNot_NullOrTrimEmpty(accNo) && accNo.indexOf("E")!=-1) {
                BigDecimal bd = new BigDecimal(accNo);
                accNo = bd.toPlainString();
            }
            result.put("accNo", accNo);

            result.put("name", param.get("持卡人姓名"));

            String certCode = param.get("持卡人身份证");
            if (StringUtils.isNot_NullOrTrimEmpty(certCode) && certCode.indexOf("E")!=-1) {
                BigDecimal bd = new BigDecimal(certCode);
                certCode = bd.toPlainString();
            }
            result.put("certCode", certCode);

            String nbr = param.get("银行卡预留手机号");
            if (StringUtils.isNot_NullOrTrimEmpty(nbr) && nbr.indexOf("E")!=-1) {
                BigDecimal bd = new BigDecimal(nbr);
                nbr = bd.toPlainString();
            }
            result.put("nbr", nbr);

            String cvn2 = param.get("信用卡CNV码(信用卡必填)") == null ? "" : param.get("信用卡CNV码(信用卡必填)");
            if (!cvn2.equals("") && cvn2.endsWith(".0")) {
                cvn2 = cvn2.substring(0,cvn2.length()-2);
            }
            result.put("cvn2", cvn2);

            String expireDate = param.get("银行号有效期月/年(信用卡必填)");
            if (expireDate != null && !expireDate.equals("") && expireDate.endsWith(".0")) {
                expireDate = expireDate.substring(0,expireDate.length()-2);
            }

            // System.out.println(expireDate);
            String originalExpireDate = expireDate;
            result.put("originalExpireDate", originalExpireDate);

            if (expireDate == null || expireDate.trim().equals("") || expireDate.length() != 4) {
                //result.put("cardType", "02");
                expireDate = "";
            } else {
                System.out.println("来到有效期处理处。。。");
                String pr = expireDate.substring(2, 4);
                String po = expireDate.substring(0, 2);
                expireDate = pr + po;
                //result.put("cardType", "01");
            }
            result.put("expireDate", expireDate);


            if (StringUtils.isNot_NullOrTrimEmpty(result.get("accNo")) && result.get("accNo").length()>6) {
                //获取银行卡卡类型
                Map<String, String> par = new HashMap<>(1, 1.0F);
                par.put("cardBin", result.get("accNo").substring(0,6));
                final String getBankInfoUrl = "http://10.95.0.233:23912/clouderp-pay-rest/api/pay/getBankCardList";

                String responseResult = HttpClientUtil.sendPostRequest(getBankInfoUrl, par, null, null);
                System.out.println("批量绑卡，根据CustCode获取MerCode  params : " + par + ", result : " + responseResult);
                result.put("cardType", null);
                try {
                    JSONObject jsonObject = JSONObject.fromObject(responseResult);
                    if (jsonObject.size() == 0 || !"000".equals(jsonObject.get("code"))) {
                    } else {
                        JSONArray datas = JSONArray.fromObject(jsonObject.get("data"));
                        if (datas.isEmpty()) {
                        }else {
                            JSONObject data = datas.getJSONObject(0);
                            result.put("cardType", data.getString("cardKind"));
                        }

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            result.put("smsCode", "123456");
            result.put("sign", "xxx");
            results.add(result);
        }
        return results;
    }

}
